package util

import (
	"errors"
	"fmt"
	"github.com/golang-jwt/jwt/v5"
	"net/http"
	"short-link/model"
	"strconv"
	"time"
)

func GenerateToken(userInfo *model.UserInfo) (string, error) {
	claims := jwt.MapClaims{}
	claims["authorized"] = true
	claims["user_id"] = userInfo.ID
	claims["platform"] = userInfo.Platform
	claims["open_id"] = userInfo.OpenId
	claims["union_id"] = userInfo.UnionId
	claims["exp"] = time.Now().Add(time.Minute * time.Duration(model.AppConfig.Secret.JwtExpired)).Unix()
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	return token.SignedString([]byte(model.AppConfig.Secret.JwtSecret))
}

func TokenValid(r *http.Request) (*model.SimpleUserInfo, error) {
	tokenString := r.Header.Get("Authorization")
	Debug("jwt: %s", tokenString)
	if len(tokenString) == 0 {
		return nil, errors.New("missing token")
	}
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}
		return []byte(model.AppConfig.Secret.JwtSecret), nil
	})
	if err != nil {
		return nil, err
	}

	claims, ok := token.Claims.(jwt.MapClaims)
	// 如果jwt有效，将user_id转换为浮点数字符串，然后再转换为 uint32
	if !(ok && token.Valid) {
		return nil, nil
	}

	uid, err := strconv.ParseInt(fmt.Sprintf("%.0f", claims["user_id"]), 10, 64)
	if err != nil {
		return nil, err
	}
	openId := claims["open_id"]
	unionId := claims["union_id"]
	platform := claims["platform"]

	info := &model.SimpleUserInfo{
		Id:       uid,
		OpenId:   openId.(string),
		UnionId:  unionId.(string),
		Platform: platform.(string),
	}
	return info, nil
}
